#region LGPL Header
// Copyright (C) 2009, Jackie Ng
// https://github.com/jumpinjackie/fdotoolbox, jumpinjackie@gmail.com
// 
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
// 
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
// 
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
// 
//
// See license.txt for more/additional licensing information
#endregion
using System;
using System.Collections.Generic;
using FdoToolbox.Core.Feature;
using OSGeo.FDO.Schema;

namespace FdoToolbox.Core.ETL.Operations
{
    /// <summary>
    /// FDO input pipeline operation
    /// </summary>
    public class FdoInputOperation : FdoOperationBase
    {
        private FdoConnection _conn;

        /// <summary>
        /// Initializes a new instance of the <see cref="FdoInputOperation"/> class.
        /// </summary>
        /// <param name="conn">The conn.</param>
        /// <param name="query">The query.</param>
        public FdoInputOperation(FdoConnection conn, FeatureQueryOptions query)
        {
            _conn = conn;
            this.Query = query;
        }

        /// <summary>
        /// Gets or sets the query.
        /// </summary>
        /// <value>The query.</value>
        public FeatureQueryOptions Query { get; set; }

        private List<string> ignoreProperties = new List<string>();

        /// <summary>
        /// Executes the operation
        /// </summary>
        /// <param name="rows"></param>
        /// <returns></returns>
        public override IEnumerable<FdoRow> Execute(IEnumerable<FdoRow> rows)
        {
            using (FdoFeatureService service = _conn.CreateFeatureService())
            {
                using (FdoFeatureReader reader = service.SelectFeatures(this.Query))
                {
                    ClassDefinition cd = reader.GetClassDefinition();
                    foreach (PropertyDefinition pd in cd.Properties)
                    {
                        if (pd.PropertyType == PropertyType.PropertyType_RasterProperty)
                            ignoreProperties.Add(pd.Name);
                        else if (pd.PropertyType == PropertyType.PropertyType_DataProperty)
                        {
                            DataPropertyDefinition dp = pd as DataPropertyDefinition;
                            if (dp.IsAutoGenerated || dp.ReadOnly)
                                ignoreProperties.Add(pd.Name);
                        }
                        else if (pd.PropertyType == PropertyType.PropertyType_GeometricProperty)
                        {
                            GeometricPropertyDefinition gp = pd as GeometricPropertyDefinition;
                            if (gp.ReadOnly)
                                ignoreProperties.Add(gp.Name);
                        }
                    }

                    while (reader.ReadNext())
                    {
                        FdoRow row = null;
                        try
                        {
                            row = CreateRowFromReader(reader);
                        }
                        catch (Exception ex)
                        {
                            if (row != null)
                            {
                                RaiseFailedFeatureProcessed(row, ex);
                            }
                            else
                            {
                                RaiseFailedReadFeature(ex.Message, ex);
                            }
                        }
                        if (row != null)
                            yield return row;
                    }
                }
            }
        }

        private FdoRow CreateRowFromReader(FdoFeatureReader reader)
        {
            return FdoRow.FromFeatureReader(reader, ignoreProperties);
        }
    }
}
